package lb.io.lblet;

import lb.io.api.core.v1.*;
import lb.io.apis.meta.v1.codes.Codez;
import lb.io.apis.meta.v1.codes.LetException;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class disk {
    /**
     * 格式化磁盘并挂载
     *
     * @param root  脚本所在的目录
     * @param dev   磁盘名称
     * @param point 磁盘挂载点
     * @return
     * @throws LetException
     */
    public static PodDiskStatus createFileDisk(String root, String dev, String point) throws LetException {
        String out = "";
        try {
            out = new LBKit.fsDisk(root, point, dev).create();
        } catch (RuntimeException e) {
            throw new LetException(Codez.ErrCreateFileDisk, e.getMessage());
        }

        return PodDiskStatus.newBuilder()
                .setKind("AIXFS")
                .setAixFS(AIXFS.newBuilder()
                        .setPv(dev)
                        .setVg(dev + "_vg")
                        .setLv(dev + "_lv")
                        .setPath(point)
                        .build())
                .setTarget(point)
                .setStore(point)
                .setState("online")
                .build();
    }

    /**
     * 格式化磁盘并挂载
     *
     * @param root  脚本所在的目录
     * @param dev   磁盘名称
     * @param point 磁盘挂载点
     * @return
     * @throws LetException
     */
    public static PodDiskStatus renameFileDisk(String root, String dev, String point) throws LetException {
        String out = "";
        try {
            out = new LBKit.fsDisk(root, point, dev).rename();
        } catch (RuntimeException e) {
            throw new LetException(Codez.ErrConnectFileDisk, e.getMessage());
        }

        return PodDiskStatus.newBuilder()
                .setKind("AIXFS")
                .setAixFS(AIXFS.newBuilder()
                        .setPv(dev)
                        .setVg(dev + "_vg")
                        .setLv(dev + "_lv")
                        .setPath(point)
                        .build())
                .setTarget(point)
                .setStore(point)
                .setState("online")
                .build();
    }

    /**
     * 卸载磁盘并删除
     *
     * @param root  脚本所在的目录
     * @param dev   磁盘名称
     * @param point 磁盘挂载点
     * @return
     * @throws LetException
     */
    public static PodDiskStatus deleteFileDisk(String root, String dev, String point) throws LetException {
        String out = "";
        try {
            out = new LBKit.fsDisk(root, point, dev).delete();
        } catch (RuntimeException e) {
            throw new LetException(Codez.ErrCreateFileDisk, e.getMessage());
        }

        return PodDiskStatus.newBuilder()
                .setKind("AIXFS")
                .setAixFS(AIXFS.newBuilder()
                        .setPv(dev)
                        .setVg(dev + "_vg")
                        .setLv(dev + "_lv")
                        .setPath(point)
                        .build())
                .setTarget(point)
                .setStore(point)
                .setState("online")
                .build();
    }

    /**
     * @param root 脚本所在目录
     * @param name 裸设备名称
     * @param dev  磁盘名称
     * @param user 创建磁盘的系统用户
     * @return
     * @throws LetException
     */
    public static AIXRawItem createRawDisk(String root, String name, String dev, String user) throws LetException {
        String out = "";
        try {
            out = new LBKit.rawDisk(root, name, dev, user).create();
        } catch (RuntimeException e) {
            throw new LetException(Codez.ErrCreateRawDisk, e.getMessage());
        }

        return AIXRawItem.newBuilder().setDev(name).build();
    }

    /**
     * @param root 脚本所在目录
     * @param name 裸设备名称
     * @param dev  磁盘名称
     * @param user 创建磁盘的系统用户
     * @return
     * @throws LetException
     */
    public static AIXRawItem deleteRawDisk(String root, String name, String dev, String user) throws LetException {
        String out = "";
        try {
            out = new LBKit.rawDisk(root, name, dev, user).delete();
        } catch (RuntimeException e) {
            throw new LetException(Codez.ErrCreateRawDisk, e.getMessage());
        }

        return AIXRawItem.newBuilder().setDev(name).build();
    }

    /**
     * 创建 diskGroup
     *
     * @param root   脚本所在目录
     * @param pod
     * @param claims
     * @return
     * @throws LetException
     */
    public static PodDiskStatus createDiskGroup(String root, Pod pod, List<PersistentVolumeClaim> claims) throws LetException {
        // 创建裸设备
        OraclePodSpec oracle = pod.getSpec().getModule().getOracle();
        AIXRaw aixRaw = AIXRaw.newBuilder().build();
        List<String> raws = new ArrayList<>();
        for (int i = 0; i < claims.size(); i++) {
            PersistentVolumeClaim claim = claims.get(i);
            String name = String.format("hl%s%d", oracle.getInstance().getDb(), i);

            AIXRawItem rawItem = createRawDisk(root, name, claim.getStatus().getDevice(), oracle.getAsm().getUser());
            aixRaw = aixRaw.toBuilder().addRaws(rawItem).build();
            raws.add(name);
        }

        PodDiskStatus disk = PodDiskStatus.newBuilder().setKind("AIXRaw").setAixRaw(aixRaw).build();

        String diskGroup = pod.getMetadata().getAnnotationsMap().get("oracleset");
        if (diskGroup.equals("")) {
            diskGroup = pod.getMetadata().getName();
        }
        diskGroup = "lb_" + diskGroup;
        OracleAttributes asm = oracle.getAsm();
        disk = disk.toBuilder()
                .setAixRaw(disk.getAixRaw().toBuilder()
                        .setGroup(diskGroup)
                        .build())
                .build();

        if (pod.getMetadata().getAnnotationsMap().containsKey("asm")) {
            OracleAttributes instance = oracle.getInstance();
            try {
                 new LBKit.diskgroup(root, diskGroup, asm.getSid(), raws)
                        .User(instance.getUser())
                        .Home(instance.getHome())
                        .Listen(instance.getListen())
                        .create();
            } catch (RuntimeException ex) {
                throw new LetException(Codez.ErrCreateDiskGroup, ex.getMessage());
            }

            disk = disk.toBuilder()
                    .setTarget(diskGroup)
                    .setStore(Paths.get(root, pod.getMetadata().getName()).toString())
                    .setState("online")
                    .build();
        }

        return disk;
    }

    public static PodDiskStatus renameDiskGroup(String root, Pod pod, List<PersistentVolumeClaim> claims) throws LetException {
        // 创建裸设备
        OraclePodSpec oracle = pod.getSpec().getModule().getOracle();
        AIXRaw aixRaw = AIXRaw.newBuilder().build();
        List<String> raws = new ArrayList<>();
        for (int i = 0; i < claims.size(); i++) {
            PersistentVolumeClaim claim = claims.get(i);
            String name = String.format("hl%s%d", oracle.getInstance().getSid(), i);

            AIXRawItem rawItem = createRawDisk(root, name, claim.getStatus().getDevice(), oracle.getAsm().getUser());
            aixRaw = aixRaw.toBuilder().addRaws(rawItem).build();
            raws.add(name);
        }

        PodDiskStatus disk = PodDiskStatus.newBuilder().setKind("AIXRaw").setAixRaw(aixRaw).build();

        String diskGroup = pod.getMetadata().getAnnotationsMap().get("oracleset");
        if (diskGroup.equals("")) {
            diskGroup = pod.getMetadata().getName();
        }
        diskGroup = "lb_" + diskGroup;
        OracleAttributes asm = oracle.getAsm();
        disk = disk.toBuilder()
                .setAixRaw(disk.getAixRaw().toBuilder()
                        .setGroup(diskGroup)
                        .build())
                .build();

        if (pod.getMetadata().getAnnotationsMap().containsKey("asm")) {
            OracleAttributes instance = oracle.getInstance();
            String source = pod.getStatus().getPodDisk().getAixRaw().getGroup();
            try {
                new LBKit.diskgroup(root, source, asm.getSid(), raws)
                        .User(instance.getUser())
                        .Home(instance.getHome())
                        .Listen(instance.getListen())
                        .rename(diskGroup);
            } catch (RuntimeException ex) {
                throw new LetException(Codez.ErrCreateDiskGroup, ex.getMessage());
            }

            disk = disk.toBuilder()
                    .setTarget(diskGroup)
                    .setStore(Paths.get(root, pod.getMetadata().getName()).toString())
                    .setState("offline")
                    .build();
        }

        return disk;
    }
}
